﻿using DEL.Webmonitor;
using SFL;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BLL.Webmonitor
{
    /// <summary>
    /// 核心功能：设计命中关键词比对方案,对传入的原始信息集合进行比对处理
    /// </summary>
    public class HitPlan
    {
        #region 初始化布隆过滤器
        /// <summary>
        /// 定义一个布隆过滤器，分配内存大小
        /// </summary>       
        public static BloomFilter bloomFilter = new BloomFilter(2000000000);
        InfoHitService InfoHitBLL = new InfoHitService();
        InfoOriginalService InfoOriginalBLL = new InfoOriginalService();

        //public HitPlan()
        //{
        //    InitBloomFilter();
        //    InitKeywords();
        //}
        
        public int InitBloomFilter()
        {
            int num = 0;
            //从数据库的infosOriginal表中将所有URL装入bloomFilter，以便下步查重
            foreach (var IO in InfoOriginalBLL.GetAllUrl())
            {
                if (bloomFilter.Contains(IO))
                {
                    continue;
                }
                else
                {
                    bloomFilter.Add(IO);
                    num = num + 1;
                }
            }

            //从数据库的infoshit表中将所有URL装入bloomFilter，以便下步查重
            //为了减少对数据库的访问，这里不查询infoshit对象了，只查询出url字段，此处不符合面向对象编程思想
            foreach (var IH in InfoHitBLL.GetAllUrl())
            {
                if (bloomFilter.Contains(IH))
                {
                    continue;
                }
                else
                {
                    bloomFilter.Add(IH);
                    num = num + 1;
                }
            }

            
            ComnTag.BloomFilterTag = true;
            return num;
        }
        #endregion
        
        #region 初始化比较用关键词列表

        //从数据库中装入关键字内容，以便下一步进行比对         
        private List<Keyword> keywords;
        private List<KeywordType2> keywordType2;
        public static List<Keyword> SJt_words;//事件关键词
        public static List<Keyword> ZTt_words;//主体关键词
        public static List<Keyword> DYt_words;//地域关键词

        KeywordService KeywordBLL = new KeywordService();
        KeywordType2Service KeywordType2BLL = new KeywordType2Service();

        /// <summary>
        /// 初始化关键词列表，用于程序加载时或者关键词发生变动后进行初始化        
        /// </summary>
        /// 因为在数据库的ZtKeywordId等三个字段（命中事件、主体、地域的二级分类）只取第一次比对中的
        /// 所要要对关键词的先后比对顺序进行控制，也就是要对关键词集合中的关键词进行排序
        /// 排序使用二级分类，所以对二级分类建立排序字段
        public void InitKeywords()
        {
            ZTt_words = new List<Keyword>();
            DYt_words = new List<Keyword>();
            keywords = KeywordBLL.GetAllEntitysList().ToList();
            keywordType2 = KeywordType2BLL.GetEntitysByLambdaAndSort(o => o.Id > 0, o => o.SortIndex, false).ToList();
            SJt_words = keywords.FindAll(c => c.KeywordType1Id == 1);//事件关键词
            foreach (KeywordType2 kt2 in keywordType2.FindAll(b => b.KeywordType1Id == 2))
            {
                ZTt_words.AddRange(keywords.FindAll(c => c.KeywordType2Id == kt2.Id));//主体关键词
            }
            foreach (KeywordType2 kt2 in keywordType2.FindAll(b => b.KeywordType1Id == 3))
            {
                DYt_words.AddRange(keywords.FindAll(c => c.KeywordType2Id == kt2.Id));//地域关键词
            }
            keywords.Clear();
            keywordType2.Clear();
            ComnTag.KeywordTag = true;
        }
        
        #endregion

        #region 命中方案
        /// <summary>
        /// 关键词命中方案一（事件驱动），如果命中事件关键词，再进行主体关键词和地域关键词比对
        /// </summary>
        public Boolean HitPlanSJ(InfoHit infoHit)
        {
            if (HitSjKeyword(infoHit))
            {
                HitZtKeyword(infoHit);
                HitDytKeyword(infoHit);
                return true;
            }
            return false;
        }

        #endregion

        #region 三类关键词（事件、主体、地域）的基本比对方法

        ///比对信息的内容和标题中是否包含事件关键字，若包含，将关键字赋值给info对象的keyword （用于前台显示）      
        private Boolean HitSjKeyword(InfoHit infoHit)
        {
            if (SJt_words.Count > 0)
            {
                //进行事件关键词比对过滤           
                foreach (Keyword w in SJt_words)
                {
                    if (infoHit.Title.Contains(w.KeywordName) || infoHit.Summary.Contains(w.KeywordName))
                    {
                        infoHit.Keyword = infoHit.Keyword + w.KeywordName + " ";
                        if (infoHit.SjKeywordId == null)       //只取第一次命中的关键词的二级类型
                            infoHit.SjKeywordId = w.KeywordType2Id;
                    }
                }
                if (infoHit.SjKeywordId != null)
                    return true;
            }
            return false;
        }

        ///比对信息的内容和标题中是否包含主体关键字，若包含，将关键字赋值给info对象的keyword        
        private Boolean HitZtKeyword(InfoHit infoHit)
        {
            if (ZTt_words.Count > 0)
            {
                //进行事件关键词比对过滤           
                foreach (Keyword w in ZTt_words)
                {
                    if (infoHit.Title.Contains(w.KeywordName) || infoHit.Summary.Contains(w.KeywordName))
                    {
                        infoHit.Keyword = infoHit.Keyword + w.KeywordName + " ";
                        if (infoHit.ZtKeywordId == null)       //只取第一次命中的关键词的二级类型
                            infoHit.ZtKeywordId = w.KeywordType2Id;
                    }
                }
                if (infoHit.ZtKeywordId != null)
                    return true;
            }
            return false;
        }

        ///比对信息的内容和标题中是否包含地域关键字，若包含，将关键字赋值给info对象的keyword        
        private Boolean HitDytKeyword(InfoHit infoHit)
        {
            if (DYt_words.Count > 0)
            {
                //进行事件关键词比对过滤           
                foreach (Keyword w in DYt_words)
                {
                    if (infoHit.Title.Contains(w.KeywordName) || infoHit.Summary.Contains(w.KeywordName))
                    {
                        infoHit.Keyword = infoHit.Keyword + w.KeywordName + " ";
                        if (infoHit.DyKeywordId == null)       //只取第一次命中的关键词的二级类型
                            infoHit.DyKeywordId = w.KeywordType2Id;
                    }
                }
                if (infoHit.DyKeywordId != null)
                    return true;
            }
            return false;
        }

        #endregion

    }
}
